import { defineComponent, useAttrs } from "vue";
import { VueDraggable } from "vue-draggable-plus";
import { h } from "vue";
import { ElCol, ElRow, ElFormItem } from "element-plus";
import RenderItem from "../render/render";

export default defineComponent({
  name: "DraggableItem",
  props: {
    currentItem: {
      type: Object,
      default: () => ({}),
    },
    index: {
      type: Number,
      default: 0,
    },
    drawingList: {
      type: Array,
      default: () => [],
    },
    activeId: {
      type: String,
      default: "",
    },
    formConf: {
      type: Object,
      default: () => ({}),
    },
  },
  setup(props) {
    const attrsRef = ref(useAttrs());

    const components = {
      itemBtns(h, currentItem, index, list) {
        const { copyItem, deleteItem } = attrsRef.value as {
          copyItem: Function;
          deleteItem: Function;
        };
        return [
          <span
            class="drawing-item-copy"
            title="复制"
            onClick={(event) => {
              copyItem(currentItem, list);
              event.stopPropagation();
            }}
          >
            <i class="el-icon-copy-document"></i>
          </span>,
          <span
            class="drawing-item-delete"
            title="删除"
            onClick={(event) => {
              deleteItem(index, list);
              event.stopPropagation();
            }}
          >
            <i class="el-icon-delete"></i>
          </span>,
        ];
      },
    };
    const layouts = {
      colFormItem(h, currentItem, index, list) {
        const { activeItem } = attrsRef.value as { activeItem: Function };
        const config = currentItem.__config__;
        const child = renderChildren(h, currentItem, index, list);
        let className =
          props.activeId === config.formId
            ? "drawing-item active-from-item"
            : "drawing-item";
        if (props.formConf.unFocusedComponentBorder)
          className += " unfocus-bordered";
        let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null;
        if (config.showLabel === false) labelWidth = "0";
        return (
          <ElCol
            span={config.span}
            class={className}
            nativeOnClick={(event) => {
              activeItem(currentItem);
              event.stopPropagation();
            }}
          >
            <ElFormItem
              label-width={labelWidth}
              label={config.showLabel ? config.label : ""}
              required={config.required}
            >
              <RenderItem
                key={config.renderKey}
                conf={currentItem}
                onInput={(event) => {
                  config.defaultValue = event;
                }}
              >
                {child}
              </RenderItem>
            </ElFormItem>
            {components.itemBtns(h, currentItem, index, list)}
          </ElCol>
        );
      },
      rowFormItem(h, currentItem, index, list) {
        const { activeItem } = attrsRef.value as { activeItem: Function };
        const config = currentItem.__config__;
        const className =
          props.activeId === config.formId
            ? "drawing-row-item active-from-item"
            : "drawing-row-item";
        let child = renderChildren(h, currentItem, index, list);
        if (currentItem.type === "flex") {
          child = (
            <ElRow
              type={currentItem.type}
              justify={currentItem.justify}
              align={currentItem.align}
            >
              {child}
            </ElRow>
          );
        }
        return (
          <ElCol span={config.span}>
            <ElRow
              gutter={config.gutter}
              class={className}
              nativeOnClick={(event) => {
                activeItem(props.currentItem);
                event.stopPropagation();
              }}
            >
              <span class="component-name">{config.componentName}</span>
              <VueDraggable
                list={config.children || []}
                animation={340}
                group="componentsGroup"
                class="drag-wrapper"
              >
                {child}
              </VueDraggable>
              {components.itemBtns(h, currentItem, index, list)}
            </ElRow>
          </ElCol>
        );
      },
      raw(h, currentItem, index, list) {
        const config = currentItem.__config__;
        const child = renderChildren(h, currentItem, index, list);
        return (
          <RenderItem
            key={config.renderKey}
            conf={currentItem}
            onInput={(event) => {
              config.defaultValue = event;
            }}
          >
            {child}
          </RenderItem>
        );
      },
    };

    const renderChildren = (h, currentItem, index, list) => {
      const config = currentItem.__config__;
      if (!Array.isArray(config.children)) return null;
      return config.children.map((el, i) => {
        const layout = layouts[el.__config__.layout];
        if (layout) {
          return layout(h, el, i, config.children);
        }
        return layoutIsNotFound();
      });
    };

    const layoutIsNotFound = () => {
      throw new Error(
        `没有与${props.currentItem.__config__.layout}匹配的layout`
      );
    };
    const layout = layouts[props.currentItem.__config__.layout];
    return () => {
      if (layout) {
        return layout(h, props.currentItem, props.index, props.drawingList);
      }
      layoutIsNotFound();
    };
  },
});
